using JT808Protocol.Common;
using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;

namespace JT808Protocol.Models.BodyParserStrategy
{
    /// <summary>
    /// 驾驶员身份信息采集上报
    /// </summary>
    public class DrDriverReport_0x0702 : IJT808Body
    {
        /// <summary>
        /// 插入或拔出状态
        /// </summary>
        [JsonPropertyName("插入或拔出状态")] public ICCardStatus Status { get; set; }//0x01插入,0x02拔出

        /// <summary>
        ///  插入或拔出的时间 BCD[6] YY-MM-DD-hh-mm-ss
        /// </summary>
        [JsonPropertyName("插入或拔出的时间")] public DateTime LogOnOffTime { get; set; }

        /// <summary>
        /// 0x00：IC 卡读卡成功；
        /// 0x01：读卡失败，原因为卡片密钥认证未通过；
        /// 0x02：读卡失败，原因为卡片已被锁定；
        /// 0x03：读卡失败，原因为卡片被拔出；
        /// 0x04：读卡失败，原因为数据校验错误。
        /// 以下字段在IC 卡读取结果等于0x00 时才有效。
        /// </summary>
        [JsonPropertyName("结果")] public EnumICCardReadingResult ReadingResult { get; set; }

        /// <summary>
        /// 驾驶员姓名长度
        /// </summary>
        [JsonPropertyName("驾驶员姓名长度")] public byte DriverNameLen { get; set; }

        /// <summary>
        /// 驾驶员姓名
        /// </summary>
        [JsonPropertyName("驾驶员姓名")] public string DriverName { get; set; }

        /// <summary>
        /// 从业资格证编码
        /// </summary>
        [JsonPropertyName("从业资格证编码")] public string QualificationCode { get; set; }

        /// <summary>
        /// 发证机构名称长度
        /// </summary>
        [JsonPropertyName("发证机构名称长度")] public byte NotifiedBodyNameLen { get; set; }

        /// <summary>
        /// 发证机构名称
        /// </summary>
        [JsonPropertyName("发证机构名称")] public string NotifiedBodyName { get; set; }

        /// <summary>
        ///  证件有效期 BCD[4] YYYYMMDD
        /// </summary>
        [JsonPropertyName("证件有效期")] public DateTime UsefulLife { get; set; }

        /// <summary>
        /// 驾驶员身份证号 长度为20字节，不足处补0
        /// </summary>
        [JsonPropertyName("身份证号码")] public string IDCardNumber { get; set; }

        public override IJT808Body ReadBody(ReadOnlySpan<byte> source, ref int startIndex)
        {
            //插入或拔出状态
            Status = (ICCardStatus)source[startIndex];//0x01插入,0x02拔出

            //插卡/拔卡时间
            LogOnOffTime = ParseHelper.BcdTo1078Datetime(ref source, startIndex + 1);

            //IC 卡读取结果
            ReadingResult = (EnumICCardReadingResult)source[startIndex + 7];//IC 卡读取结果
            if (ReadingResult != EnumICCardReadingResult.IC读卡成功)
            {
                throw new Exception($"IC卡读取异常,结果:{ReadingResult}");
            }

            //驾驶员姓名长度
            DriverNameLen = source[startIndex + 8];

            //驾驶员姓名
            DriverName = ParseHelper.Gb2312String(ref source, startIndex + 9, DriverNameLen).Trim();

            //从业资格证编码
            QualificationCode = ParseHelper.Gb2312String(ref source, startIndex + 9 + DriverNameLen, 20).Trim('\0');

            //发证机构名称长度
            NotifiedBodyNameLen = source[startIndex + DriverNameLen + 29];

            //发证机构名称
            NotifiedBodyName = ParseHelper.Gb2312String(ref source, startIndex + DriverNameLen + 30, NotifiedBodyNameLen).Trim('\0');

            //证件有效期
            UsefulLife = ParseHelper.BcdTo1078Date(ref source, startIndex + DriverNameLen + 30 + NotifiedBodyNameLen);

            if (HeaderContext.ProtocolVersion == JT808ProtocolVersion.v2019)
            {
                //身份证号码
                IDCardNumber = ParseHelper.Gb2312String(ref source, startIndex + DriverNameLen + 34 + NotifiedBodyNameLen, 20).Trim('\0');
            }

            return this;
        }

        public override List<byte> WriteToBytes()
        {
            throw new NotImplementedException();
        }
    }

    /// <summary>
    /// IC卡状态
    /// </summary>
    public enum ICCardStatus : byte
    {
        从业资格证IC卡插入 = 0x01,
        从业资格证IC卡拔出 = 0x02
    }

    /// <summary>
    /// IC卡读取结果
    /// </summary>
    public enum EnumICCardReadingResult : byte
    {
        IC读卡成功 = 0x00,
        读卡失败_原因为卡片密钥认证未通过 = 0x01,
        读卡失败_原因为卡片已被锁定 = 0x02,
        读卡失败_原因为卡片被拔出 = 0x03,
        读卡失败_原因为数据校验错误 = 0x04,
    }
}